home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
os2
/
yeah09.zip
/
source
/
lib
/
ea.cpp
next >
Wrap
C/C++ Source or Header
|
1996-05-25
|
11KB
|
463 lines
//------------------------------------------------------------
//
// Name: ea.cpp
// Version: 0.9
// Author: Björn Fahller.
//
// Copyright (C) Björn Fahller, 1996.
//
// Purpose: Base class for extended attributes. The "engine" in
// YEAH.
//
// History:
// Ver. Date What
// 0.9 1996-05-26 First official release.
//
//------------------------------------------------------------
#include <IString.hpp>
#include <string.h>
#include "YEA.H"
#define INCL_DOSFILEMGR
#include <os2.h>
#include <strstrea.h>
#include <fstream.h>
#include <IExcBase.hpp>
//////////////
//
// Prototypes of static functions.
//
//////////////
IEXCLASSIMPLEMENT(EAError, IException);
IEXCLASSIMPLEMENT(EAReadError, EAError);
IEXCLASSIMPLEMENT(EAWriteError, EAError);
IEXCLASSIMPLEMENT(EATypeMismatchError, EAError);
static EA::CreatorMap defaultEAInit(void);
void setupGEA(EAOP2* peaop2, const IString& name);
EA* createFrom(EAOP2* peaop2, const EA::CreatorMap& cm);
static char* prepareFEA(EAOP2* peaop2, const IString& name);
static EA::NameSet nameset(ULONG type, PVOID p);
static void defaultErrorHandler(EA::Error, ULONG);
//////////////
//
// Definition of class static variables
//
/////////////
inline EA::CreatorMap defaultEAInit(void)
{
return EA::CreatorMap();
}
EA::CreatorMap EA::defaultCreatorMap = defaultEAInit();
void (*EA::errorHandler)(EA::Error, ULONG) = defaultErrorHandler;
/////////////
//
// Public methods
//
/////////////
EA::~EA(void)
{
}
void EA::getFrom(const IString& file, const IString& name)
{
peaop2 = new EAOP2;
peaop2->fpGEA2List = (GEA2LIST*)new char[500];
peaop2->fpFEA2List = (FEA2LIST*)new char[65536];
::setupGEA(peaop2, name);
APIRET rc = DosQueryPathInfo(file, FIL_QUERYEASFROMLIST, peaop2, sizeof(*peaop2));
if (rc)
{
delete peaop2->fpGEA2List;
delete peaop2->fpFEA2List;
delete peaop2;
peaop2 = 0;
errorHandler(ReadError, rc);
return;
}
feaproc();
delete peaop2->fpGEA2List;
delete peaop2->fpFEA2List;
delete peaop2;
peaop2 = 0;
}
void EA::getFrom(fstreambase& file, const IString& name)
{
peaop2 = new EAOP2;
peaop2->fpGEA2List = (GEA2LIST*)new char[500];
peaop2->fpFEA2List = (FEA2LIST*)new char[65536];
::setupGEA(peaop2, name);
APIRET rc = DosQueryFileInfo(file.rdbuf()->fd(), FIL_QUERYEASFROMLIST, peaop2, sizeof(*peaop2));
if (rc)
{
delete peaop2->fpGEA2List;
delete peaop2->fpFEA2List;
delete peaop2;
peaop2 = 0;
errorHandler(ReadError, rc);
return;
}
feaproc();
delete peaop2->fpGEA2List;
delete peaop2->fpFEA2List;
delete peaop2;
peaop2 = 0;
}
void EA::storeTo(const IString& file, const IString& name)
{
peaop2 = new EAOP2;
peaop2->fpGEA2List = (GEA2LIST*)new char[500];
peaop2->fpFEA2List = (FEA2LIST*)new char[65536];
setupFEA(name);
APIRET rc = DosSetPathInfo(file, FIL_QUERYEASIZE, peaop2, sizeof(*peaop2), 0);
delete peaop2->fpGEA2List;
delete peaop2->fpFEA2List;
delete peaop2;
peaop2 = 0;
if (rc)
{
errorHandler(WriteError, rc);
}
}
void EA::storeTo(fstreambase& file, const IString& name)
{
peaop2 = new EAOP2;
peaop2->fpGEA2List = (GEA2LIST*)new char[500];
peaop2->fpFEA2List = (FEA2LIST*)new char[65536];
setupFEA(name);
APIRET rc = DosSetFileInfo(file.rdbuf()->fd(), FIL_QUERYEASIZE, peaop2, sizeof(*peaop2));
delete peaop2->fpGEA2List;
delete peaop2->fpFEA2List;
delete peaop2;
peaop2 = 0;
if (rc)
{
errorHandler(WriteError, rc);
}
}
/////////////
//
// Protected methods
//
/////////////
EA::EA(EA::Identifier anId)
: id(anId),
flags(0),
peaop2(0)
{
}
EA::EA(const EA& e)
: id(e.id),
flags(e.flags),
peaop2(0)
{
}
const EA& EA::operator=(const EA& e)
{
id = e.id;
flags = e.flags;
return *this;
}
/////////////
//
// Private methods
//
/////////////
void EA::setupFEA(const IString& name)
{
char* p = ::prepareFEA(peaop2, name);
EAOP2& eaop2 = *peaop2;
ostrstream os(p, 65536-((char*)eaop2.fpFEA2List-p));
os.write((char*)&id, sizeof(id));
writeTo(os);
os.seekp(0, ios::end);
unsigned long length = os.tellp();
eaop2.fpFEA2List->list[0].cbValue = (USHORT)length;
eaop2.fpFEA2List->list[0].fEA = flags;
eaop2.fpFEA2List->cbList = length + p-(char*)eaop2.fpFEA2List;
if (eaop2.fpFEA2List->cbList % 4)
{
eaop2.fpFEA2List->cbList+= 4-(eaop2.fpFEA2List->cbList % 4);
}
}
void EA::feaproc(void)
{
EAOP2& eaop2 = *peaop2;
if (eaop2.fpFEA2List->list[0].cbValue == 0)
{
errorHandler(NoSuchEAError, 0);
return;
}
istrstream is(eaop2.fpFEA2List->list[0].szName+eaop2.fpFEA2List->list[0].cbName+1,
eaop2.fpFEA2List->list[0].cbValue);
Identifier type;
is.read((char*)(&type), sizeof(type));
if (type != id)
{
errorHandler(TypeMismatchError, type);
return;
}
flags = eaop2.fpFEA2List->list[0].fEA;
readFrom(is);
}
/////////////
//
// Static methods
//
/////////////
void EA::remove(const IString& file, const IString& name)
{
EAOP2 eaop2;
eaop2.fpFEA2List = (FEA2LIST*)new char[1024];
eaop2.fpGEA2List = 0;
eaop2.oError = 0;
char* p = ::prepareFEA(&eaop2, name);
eaop2.fpFEA2List->list[0].cbValue = 0;
eaop2.fpFEA2List->list[0].fEA = 0;
eaop2.fpFEA2List->cbList = p-(char*)eaop2.fpFEA2List;
if (eaop2.fpFEA2List->cbList % 4)
{
eaop2.fpFEA2List->cbList+= 4-(eaop2.fpFEA2List->cbList % 4);
}
APIRET rc = DosSetPathInfo(file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), 0);
delete eaop2.fpFEA2List;
if (rc)
{
errorHandler(WriteError, rc);
}
}
void EA::remove(fstreambase& file, const IString& name)
{
EAOP2 eaop2;
eaop2.fpFEA2List = (FEA2LIST*)new char[1024];
eaop2.fpGEA2List = 0;
eaop2.oError = 0;
char* p = ::prepareFEA(&eaop2, name);
eaop2.fpFEA2List->list[0].cbValue = 0;
eaop2.fpFEA2List->list[0].fEA = 0;
eaop2.fpFEA2List->cbList = p-(char*)eaop2.fpFEA2List;
if (eaop2.fpFEA2List->cbList % 4)
{
eaop2.fpFEA2List->cbList+= 4-(eaop2.fpFEA2List->cbList % 4);
}
APIRET rc = DosSetFileInfo(file.rdbuf()->fd(), FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
delete eaop2.fpFEA2List;
if (rc)
{
errorHandler(WriteError, rc);
}
}
EA* EA::newFrom(const IString& file, const IString& name, const CreatorMap& cm)
{
EAOP2 eaop2;
eaop2.oError = 0;
eaop2.fpFEA2List = (FEA2LIST*)new char[500];
eaop2.fpGEA2List = (GEA2LIST*)new char[65536];
::setupGEA(&eaop2, name);
APIRET rc = DosQueryPathInfo(file, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
if (rc)
{
delete eaop2.fpFEA2List;
delete eaop2.fpGEA2List;
errorHandler(ReadError, rc);
return 0;
}
EA* pea = createFrom(&eaop2, cm);
delete eaop2.fpFEA2List;
delete eaop2.fpGEA2List;
return pea;
}
EA* EA::newFrom(fstreambase& file, const IString& name, const CreatorMap& cm)
{
EAOP2 eaop2;
eaop2.oError = 0;
eaop2.fpFEA2List = (FEA2LIST*)new char[500];
eaop2.fpGEA2List = (GEA2LIST*)new char[65536];
::setupGEA(&eaop2, name);
APIRET rc = DosQueryFileInfo(file.rdbuf()->fd(), FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
if (rc)
{
delete eaop2.fpFEA2List;
delete eaop2.fpGEA2List;
errorHandler(ReadError, rc);
return 0;
}
EA* pea = createFrom(&eaop2, cm);
delete eaop2.fpFEA2List;
delete eaop2.fpGEA2List;
return pea;
}
EA::NameSet EA::namesIn(const IString& name)
{
return nameset(ENUMEA_REFTYPE_PATH, (PVOID)(char*)name);
}
EA::NameSet EA::namesIn(fstreambase& file)
{
return nameset(ENUMEA_REFTYPE_FHANDLE, (PVOID)(file.rdbuf()->fd()));
}
////////////
//
// Static functions
//
////////////
static EA::NameSet nameset(ULONG type, PVOID p)
{
DENA2* pdena = (DENA2*)new char[65364];
pdena->oNextEntryOffset = 0;
pdena->cbValue = 0;
pdena->cbName = 0;
pdena->fEA = 0;
LONG count = -1;
APIRET rc = DosEnumAttribute(type, p, 1, (PVOID)pdena,